//webpack打包入口文件

const path = require('path');
const HTMLPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const ExtractPlugin = require('extract-text-webpack-plugin');

//package里设置的属性都会存在process.env对象里
const isDev = process.env.NODE_ENV === 'development';
;

const config = {
  target: 'web',
  //入口路径：__dirname当前文件路径 两个拼接起来就是入口文件路径
  entry: path.join(__dirname, 'src/index.js'),
  //输出路径
  output: {
    //输出文件名称
    filename: 'bundle.[hash:8].js',
    //输出路径
    path: path.join(__dirname, 'dist')
  },
  //处理文件
  module: {
    //处理规则
    rules: [
      {
        //检查对象为vue结尾的文件，这是正则表达式
        test: /\.vue$/,
        //分配的处理器为vue-loader
        loader: 'vue-loader'
      },
      {
        test: /\.jsx$/,
        loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        //用loader不能完全达到效果
        //loader: 'css-loader',
        use: [
          //一定要按照这个顺序，loader的加载顺序是从右往左，从下往上
          //把css写入到js中，将css插入到页面的style标签
          'style-loader',
          //翻译css为CommonJS 处理css文件中的url()等
          'css-loader'
        ]
      }
      ,
      {
        test: /\.(gif|jpg|jpeg|png|svg)$/,
        use: [
          //使用对象可以对处理器进行设置
          {
            //把图片转成base64代码写在js代码中，不用重新生成一个文件
            loader: 'url-loader',
            options: {
              //判断当图片小于1024时才会去转换
              limit: 1024,
              //当大于1024时生成文件的名字
              //[name]原文件的名字，[ext]原文件的扩展名,通过这个可以修改生成的文件名
              name: '[name]-img.[ext]'
            }


          }
        ]
      }
    ]

  },
  //插件设置
  plugins: [
    //在使用vue等框架时一定要用webpack.DefinePlugin插件，在打包时会根据是开发还是生产进行框架不同源代码的打包，开发环境有各种提示信息和错误提醒，生产环境就不需要了
    //打包时开发环境可以打包源代码比如vue.js其中包含各种提示信息，生产环境打包压缩干净的源代码比如vue.min.js
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: isDev ? '"development"' : '"production"'
      }
    }),
    //创建html文件，容纳入口js文件
    new HTMLPlugin()
  ]
};

if (isDev) {
  config.module.rules.push(
      {
        test: /\.less$/,
        use: [
          //一定要按照这个顺序，loader的加载顺序是从右往左，从下往上
          //把css写入到js中，将css插入到页面的style标签
          'style-loader',
          //翻译css为CommonJS 处理css文件中的url()等
          'css-loader',
          {
            //处理css,比如加上特定浏览器css前缀
            loader: 'postcss-loader',
            options: {
              //直接使用上一步生成的css，这样可以增加效率
              sourceMap: true
            }
          },
          //编译less为css
          'less-loader'

        ]
      },
      {
        test: /\.styl$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              sourceMap: true
            }
          },
          'stylus-loader'

        ]
      }
  );
  //帮助页面调试代码，es6在浏览器不能直接运行，页面上的代码都是进过编译的，我们都不认识
  //对源代码进行映射，这样在浏览器上就是我们自己写的代码,有很多不同的映射方法，可以自己设置，webpack官方推荐#cheap-module-eval-source-map
  config.devtool = '#cheap-module-eval-source-map'
  //devServer是在webpack 2时加上的，1的时候没有
  config.devServer = {
    port: 8000,
    //也可以设置为localhost、127.0.0.1，但没有0.0.0.0好
    //设置为0.0.0.0可以访问localhost、127.0.0.1，也可以用本机内网IP访问，这样在别人电脑和手机都可以访问
    host: '0.0.0.0',
    overlay: {
      //出现错误时，显示在网页上
      errors: true,
    },
    //启动后自动打开浏览器
    //open:true,
    //修改js代码后，只重新渲染被改代码的组件，不重新加载整个页面，导致其他组件数据消失,即只刷新数据，不刷新页面
    hot: true,
  };
  config.plugins.push(
      //hot:true启用这个插件
      new webpack.HotModuleReplacementPlugin(),
      //在编译出现错误时，使用 NoEmitOnErrorsPlugin 来跳过输出阶段。这样可以确保输出资源不会包含错误
      new webpack.NoEmitOnErrorsPlugin()
  );

} else {
  config.entry = {
    app: path.join(__dirname, 'src/index.js'),
    vendor: ['vue']
  };
  config.output.filename = '[name].[chunkhash:8].js'
  config.module.rules.push({
    test: /\.styl/,
    use: ExtractPlugin.extract({
      fallback: 'style-loader',
      use: [
        'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            sourceMap: true
          }
        },
        'stylus-loader'
      ]
    })
  }, {
    test: /\.less/,
    use: ExtractPlugin.extract({
      fallback: 'style-loader',
      use: [
        'css-loader',
        {
          loader: 'postcss-loader',
          options: {
            sourceMap: true
          }
        },
        'less-loader'
      ]
    })
  });
  config.plugins.push(
      //拆分出样式
      new ExtractPlugin('styles.[contentHash:8].css'),
      //设置需拆分的框架,生成vendor文件
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor'
      }),
      //入口节点的公共代码拆分,一定要在框架拆分的下面,生成文件runtime
      new webpack.optimize.CommonsChunkPlugin({
        name: 'runtime'
      })
  )
}

module.exports = config;